《Java8实战》 | Chapter1 为什么要关心Java8
Part1. 基础知识篇
Chapter1. 为什么要关心Java8
1. 代码变得更加简洁,这些代码读起来更接近问题的描述
原来:1
2
3
4
5Collections.sort(inventory, new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}
});
现在:1
inventory.sort(comparing(Apple::getWeight));
2. 对硬件也有影响
- 在Java8以前,需要利用线程才能使用多个内核。
- Java 1.0 中有线程和锁,甚至有一个内存模型。
- Java 5 添加了工业级的构建模块,如线程池和并发集合
- Java 7 添加了分支/合并(Fork/Join)框架,使得并行变得更实用,但仍然很困难
- Java 8 对并行有了一个更简单的新思路,有更简洁的代码,且更简单地使用了多核处理器。
3. Java8 提供了一个新的API(流,Stream),支持许多处理数据的并行操作
在Java8中加入Stream可以看作另外两项扩充加入Java8中的直接原因:
- 把代码传递给方法的简洁方式(方法引用、Lambda),这种方式简洁地表达了行为参数化,这种方式也可以让我们使用函数式编程的编程技巧。函数可以被来回传递并加以组合,以产生强大的编程语汇。
- 接口中的默认方法
4. 几个关键概念
1) 流处理
2) 行为参数化,把代码传递给方法
3) 并行与共享的可变数据
- 纯函数(无副作用函数、无状态函数)
- 没有共享的可变数据,将方法和函数即代码传递给其他方法的能力,是函数式编程范式的基石
4) 方法和Lambda作为一等公民,方法引用、Lambda匿名函数(将函数作为值)
5) 外部迭代(for-each,自己去迭代集合处理元素)和内部迭代(Stream API,在库内部进行元素处理)
6) Collection API主要是为了存储和访问数据;Stream API主要用于描述对数据的计算,并且Stream提倡并行处理一个Stream中的元素,筛选一个Collection的最快方法通常是将其转换为Stream进行并行处理然后再转回为List,如1
list.stream().filter((Apple a) -> a.getWeight() > 150).collect(Collectors.toList());
7) 默认方法,给接口设计者提供了一个扩充接口的方式,而不会破坏现有的代码。Java8在接口中使用新的default关键字来表示这一点。例如,以前需要Collection.sort(aList,aComparator),在Java8中可以直接对List调用sort方法,sort采用了默认方法,调用Collections.sort静态方法,这样List的任何实现类都不需要显式实现sort,否则会编译失败1
2
3default void sort(Comparator<? super E> c) {
Collections.sort(this, c);
}
8) 来自函数式编程的好思想:
- 将方法和Lambda作为一等公民
- 在没有可变共享状态时,函数可以有效且安全地并行执行
- 处理null问题:Optional
类,避免NPE异常 - (结构)模式匹配,函数是分情况定义的,而不是使用if-then-else
- 更好地利用多核处理器